// ==============================================================
//
//  Copyright (c) 1999-2002 by Alex Vinokur.  This work and all works
//  derived from it may be copied and modified without any
//  restrictions other than that a copy of this copyright notice
//  must be included in any copy of this work or any derived work.
//
// ==============================================================

static char id [] = "@(#)## n-ary Huffman Template Algorithm ## Author : Alex Vinokur ## "__FILE__;


// ##############################################################
// =================================
//  n-ary Huffman Template Algorithm
// ==================================
//
//  FILE : democase.cpp
//
//  AUTHOR : Alex Vinokur
//
//  DESCRIPTION :
//
//         Implementation of the test cases
//         --------------------------------
//
// ##############################################################


// ===========================
#include "democase.h"
// ===========================

#define	SEE_ME_AT	\
	cout	<< endl		\
		<< endl		\
		<< endl		\
		<< "\t------> "	\
		<< "=================="	\
		<< endl		\
		<< "\t------> "	\
		<< "Test-Group#"	\
		<< inst_type_	\
		<< endl		\
		<< "\t------> "	\
		<< "      See : "	\
		<< endl		\
		<< "\t------> "	\
		<< "------------------"	\
		<< endl		\
		<< "\t------> "	\
		<< __FILE__	\
		<< ", #"	\
		<< __LINE__	\
		<< endl		\
		<< "\t------> "	\
		<< __PRETTY_FUNCTION__	\
		<< endl		\
		<< "\t------> "	\
		<< "------------------"	\
		<< endl		\
		<< "\t------> "	\
		<< file_name_i	\
		<< ", #"	\
		<< line_no_i	\
		<< endl		\
		<< "\t------> "	\
		<< func_name_i	\
		<< endl		\
		<< "\t------> "	\
		<< "=================="	\
		<< endl




// ===========================
static vector<char>    vector_source_msg__s;
static vector<CODE>    vector_encoded_msg__s;
static vector<char>    vector_decoded_msg__s;

static string          string_source_msg__s;
static string          string_encoded_msg_s;
static string          string_decoded_msg__s;



// ===========================
// Constructor-0
ClassTest::ClassTest (int inst_type_i)
{
	inst_type_ = inst_type_i;
	switch (inst_type_)
	{
		case 1 :
		default :
			init1_data_vectors ();
			init1_weights_vectors ();

			set1_data_files_name ();
			set1_weights_files_name ();

			break;

		case 2 :
			init2_data_vectors ();
			init2_weights_vectors ();

			set2_data_files_name ();
			set2_weights_files_name ();

			break;

	}
}

// ===========================
// Destructor
ClassTest::~ClassTest ()
{
}


// ===========================
void ClassTest::init1_data_vectors ()
{
	// --- char_int_data_vector ---
	for (unsigned char cur_char = 0x20; cur_char < 0x7d; cur_char++)
        {
		char_int_data_vector_.push_back (Cell<char, int> (cur_char, ((cur_char%19 + 3)) * 7));
        }


	// --- string_float_data_vector ---
        string_float_data_vector_.push_back (Cell<string, float> ("a1", 0.0022));
        string_float_data_vector_.push_back (Cell<string, float> ("aa22", 0.002));
        string_float_data_vector_.push_back (Cell<string, float> ("aaa333", 0.02));
        string_float_data_vector_.push_back (Cell<string, float> ("bx1", 0.0001));
        string_float_data_vector_.push_back (Cell<string, float> ("bbyy22", 0.007));
        string_float_data_vector_.push_back (Cell<string, float> ("czzz1", 0.0013));
        string_float_data_vector_.push_back (Cell<string, float> ("cczzzzz22", 0.003));
        string_float_data_vector_.push_back (Cell<string, float> ("ccczzzzzzzz333", 0.023));


	// --- AAA_BBB_data_vector ---
        for (unsigned int the_index = 0;
                          the_index < 5;
                          the_index++)
        {
                AAA_BBB_data_vector_.push_back (Cell<AAA, BBB> ());
        }
}

// ===========================
void ClassTest::init1_weights_vectors ()
{
	// --- int_weights_vector ---
        int_weights_vector_.push_back (1);
        int_weights_vector_.push_back (1);
const unsigned int      this_start_index = int_weights_vector_.size ();
        for (unsigned int the_index = this_start_index;
                          the_index < (this_start_index + 21);
                          the_index++)
        {
                int_weights_vector_.push_back (int_weights_vector_ [the_index - 2] + int_weights_vector_ [the_index - 1]);
        }
}



// ===========================
void ClassTest::init2_data_vectors ()
{
	// --- char_int_data_vector ---
	for (unsigned char cur_char = 0x20; cur_char < 0x7d; cur_char++)
        {
		char_int_data_vector_.push_back (Cell<char, int> (cur_char, ((cur_char%29 + 3)) * 7));
        }


	// --- string_float_data_vector ---
        string_float_data_vector_.push_back (Cell<string, float> ("a1", 0.0035));
        string_float_data_vector_.push_back (Cell<string, float> ("aa22", 0.002));
        string_float_data_vector_.push_back (Cell<string, float> ("aaa333", 0.02));
        string_float_data_vector_.push_back (Cell<string, float> ("bx1", 0.001));
        string_float_data_vector_.push_back (Cell<string, float> ("bbyy22", 0.0007));
        string_float_data_vector_.push_back (Cell<string, float> ("czzz1", 0.0013));
        string_float_data_vector_.push_back (Cell<string, float> ("cczzzzz22", 0.103));
        string_float_data_vector_.push_back (Cell<string, float> ("ccczzzzzzzz333", 0.023));
        string_float_data_vector_.push_back (Cell<string, float> ("xyz", 0.101));


	// --- AAA_BBB_data_vector ---
        for (unsigned int the_index = 0;
                          the_index < 7;
                          the_index++)
        {
                AAA_BBB_data_vector_.push_back (Cell<AAA, BBB> ());
        }
        AAA_BBB_data_vector_.push_back (Cell<AAA, BBB> (AAA(), BBB()));
        AAA_BBB_data_vector_.push_back (Cell<AAA, BBB> (AAA(), BBB()));
        AAA_BBB_data_vector_.push_back (Cell<AAA, BBB> (AAA(), BBB()));
        AAA_BBB_data_vector_.push_back (Cell<AAA, BBB> (AAA(), BBB()));
}

// ===========================
void ClassTest::init2_weights_vectors ()
{
	// --- int_weights_vector ---
        int_weights_vector_.push_back (1);
        int_weights_vector_.push_back (1);
const unsigned int      this_start_index = int_weights_vector_.size ();
        for (unsigned int the_index = this_start_index;
                          the_index < (this_start_index + 35);
                          the_index++)
        {
                int_weights_vector_.push_back (int_weights_vector_ [the_index - 2] + int_weights_vector_ [the_index - 1]);
        }
}




// ===========================
void ClassTest::set1_data_files_name ()
{
#define DEMO_DATA_FILE_01	"data_file_01.txt"	
	char_int_data_file_name_ = string(DEMO_DATA_FILE_01);
}

// ===========================
void ClassTest::set2_data_files_name ()
{
#define DEMO_DATA_FILE_02	"data_file_02.txt"	
	char_int_data_file_name_ = string(DEMO_DATA_FILE_02);
}

// ===========================
void ClassTest::set1_weights_files_name ()
{
#define DEMO_WEIGHTS_FILE_01	"weights_file_01.txt"	
	int_weights_file_name_ = string(DEMO_WEIGHTS_FILE_01);
}

// ===========================
void ClassTest::set2_weights_files_name ()
{
#define DEMO_WEIGHTS_FILE_02	"weights_file_02.txt"	
	int_weights_file_name_ = string(DEMO_WEIGHTS_FILE_02);
}



// ===========================
void ClassTest::show_char_int_data_vector () const
{
	cout << endl;
	cout << "Data vector (symbols & weights) : ";
	// --- char_int_data_vector ---
	for (int i = 0; i < char_int_data_vector_.size(); i++)
	{
		cout << char_int_data_vector_[i] << " ";
	}
	cout << endl;
}

// ===========================
void ClassTest::show_string_float_data_vector () const
{
	cout << endl;
	cout << "Data vector (symbols & weights) : ";
	// --- string_float_data_vector ---
	for (int i = 0; i < string_float_data_vector_.size(); i++)
	{
		cout << string_float_data_vector_[i] << " ";
	}
	cout << endl;
}



// ===========================
void ClassTest::show_AAA_BBB_data_vector () const
{
	cout << endl;
	cout << "Data vector (symbols & weights) : ";
	// --- AAA_BBB_data_vector ---
	for (int i = 0; i < AAA_BBB_data_vector_.size(); i++)
	{
		cout << AAA_BBB_data_vector_[i] << " ";
	}
	cout << endl;
}




// ===========================
void ClassTest::show_int_weights_vector () const
{
	cout << endl;
	cout << "Weights vector : ";
	// --- int_weights_vector ---
	for (int i = 0; i < int_weights_vector_.size(); i++)
	{
		cout << int_weights_vector_[i] << " ";
	}
	cout << endl;
}


// ===========================
void ClassTest::demo_case_t01 (
	const string&	file_name_i, 
	size_t		line_no_i,
	const string&	func_name_i
	) const
{
SEE_ME_AT;
LoadedHuffmanTree<char, int, 5>         the_tree (char_int_data_vector_);
	show_char_int_data_vector ();
        the_tree.showAll ("Test#t1 : Creating Loaded 5-ary Huffman Tree from <char, int>-data vector");
} 


// ===========================
void ClassTest::demo_case_t02 (
	const string&	file_name_i, 
	size_t		line_no_i,
	const string&	func_name_i
	) const
{
SEE_ME_AT;
LoadedHuffmanTree<char, int, 24>        the_tree (char_int_data_vector_);
	show_char_int_data_vector ();
        the_tree.showAll ("Test#t2 : Creating Loaded 24-ary Huffman Tree from <char, int>-data vector");
}


// ===========================
void ClassTest::demo_case_t03 (
	const string&	file_name_i, 
	size_t		line_no_i,
	const string&	func_name_i
	) const
{
SEE_ME_AT;
LoadedHuffmanTree<char, int>            the_tree (char_int_data_vector_);
	show_char_int_data_vector ();
        the_tree.showAll ("Test#t3 : Creating Loaded Binary Huffman Tree from <char, int>-data vector");
}

// ===========================
void ClassTest::demo_case_t04 (
	const string&	file_name_i, 
	size_t		line_no_i,
	const string&	func_name_i
	) const
{
SEE_ME_AT;
DriedHuffmanTree<int>   the_tree (int_weights_vector_);
	show_int_weights_vector ();
        the_tree.showAll ("Test#t4 : Creating Dried Binary Huffman Tree from <int>-weights vector (Fibonacci sequence)");
}

// ===========================
void ClassTest::demo_case_t05 (
	const string&	file_name_i, 
	size_t		line_no_i,
	const string&	func_name_i
	) const
{
SEE_ME_AT;
DriedHuffmanTree<int>   the_tree (int_weights_file_name_);
	show_file ("Weights", int_weights_file_name_);
        the_tree.showAll ("Test#t5 : Creating Dried Binary Huffman Tree from <int>-weights file");
}

// ===========================
void ClassTest::demo_case_t06 (
	const string&	file_name_i, 
	size_t		line_no_i,
	const string&	func_name_i
	) const
{
SEE_ME_AT;
LoadedHuffmanTree<char, int>    the_tree (char_int_data_file_name_);
	show_file ("Data", char_int_data_file_name_);
        the_tree.showAll ("Test#t6 : Creating Loaded Binary Huffman Tree from <char, int>-data file");
}

// ===========================
void ClassTest::demo_case_t07 (
	const string&	file_name_i, 
	size_t		line_no_i,
	const string&	func_name_i
	) const
{
SEE_ME_AT;
LoadedHuffmanTree<string, float>                the_tree (string_float_data_vector_);
	show_string_float_data_vector ();
        the_tree.showAll ("Test#t7 : Creating Loaded Binary Huffman Tree from <string, float>-data vector");
}

// ===========================
void ClassTest::demo_case_t08 (
	const string&	file_name_i, 
	size_t		line_no_i,
	const string&	func_name_i
	) const
{
SEE_ME_AT;
LoadedHuffmanTree<AAA, BBB>             the_tree (AAA_BBB_data_vector_);
	show_AAA_BBB_data_vector ();
        the_tree.showAll ("Test#t8 : Creating Loaded Binary Huffman Tree from <AAA, BBB>-data vector");
}


// ===========================
void ClassTest::demo_case_m01 (
	const string&	file_name_i, 
	size_t		line_no_i,
	const string&	func_name_i
	) const
{
SEE_ME_AT;
LoadedHuffmanTree<char, int, 5>         the_tree (char_int_data_vector_);
	show_char_int_data_vector ();

        // ============ vector msg ===============================
        cout << endl << "\tTest#mv1 : Encoding and Decoding vector-message using 5-ary Huffman Tree" << endl;

        fill_vector (vector_source_msg__s, string ("Hi, people! This is vector message from 5-ary Huffman Tree"));

        cout << "Source Message  : " << gstr_vector (vector_source_msg__s) << endl;

        if (the_tree.encodeMsg (vector_source_msg__s, vector_encoded_msg__s))
        {
                cout << "Encoded Message : " << gstr_vector (vector_encoded_msg__s) << endl;
        }
        else
        {
                cout << "Cannot encode Message <" << gstr_vector (vector_source_msg__s) << ">" << endl;
        }
        if (the_tree.decodeMsg (vector_encoded_msg__s, vector_decoded_msg__s))
        {
                cout << "Decoded Message : " << gstr_vector (vector_decoded_msg__s) << endl;
        }
        else
        {
                cout << "Cannot decode encoded Message <" << gstr_vector (vector_encoded_msg__s) << ">" << endl;
        }



        // ============ string msg ===============================
        cout << endl << "\tTest#ms1 : Encoding and Decoding string-message using 5-ary Huffman Tree" << endl;

        string_source_msg__s = "Hi, people! This is string message from 5-ary Huffman Tree";

        cout << "Source Message  : " << string_source_msg__s << endl;

        if (the_tree.encodeMsg (string_source_msg__s, string_encoded_msg_s))
        {
                cout << "Encoded Message : " << string_encoded_msg_s << endl;
        }
        else
        {
                cout << "Cannot encode Message <" << string_source_msg__s << ">" << endl;
        }

        if (the_tree.decodeMsg (string_encoded_msg_s, string_decoded_msg__s))
        {
                cout << "Decoded Message : " << string_decoded_msg__s << endl;
        }
        else
        {
                cout << "Cannot decode encoded Message <" << string_encoded_msg_s << ">" << endl;
        }

} 



// ===========================
void ClassTest::demo_case_m02 (
	const string&	file_name_i, 
	size_t		line_no_i,
	const string&	func_name_i
	) const
{
SEE_ME_AT;
LoadedHuffmanTree<char, int>            the_tree (char_int_data_vector_);
	show_char_int_data_vector ();

        // ============ vector msg ===============================
        cout << endl << "\tTest#mv2 : Encoding and Decoding vector-message using Binary Huffman Tree" << endl;

        fill_vector (vector_source_msg__s, string ("Hi, people! This is vector message from Binary Huffman Tree"));

        cout << "Source Message  : " << gstr_vector (vector_source_msg__s) << endl;

        if (the_tree.encodeMsg (vector_source_msg__s, vector_encoded_msg__s))
        {
                cout << "Encoded Message : " << gstr_vector (vector_encoded_msg__s) << endl;
        }
        else
        {
                cout << "Cannot encode Message <" << gstr_vector (vector_source_msg__s) << ">" << endl;
        }
        if (the_tree.decodeMsg (vector_encoded_msg__s, vector_decoded_msg__s))
        {
                cout << "Decoded Message : " << gstr_vector (vector_decoded_msg__s) << endl;
        }
        else
        {
                cout << "Cannot decode encoded Message <" << gstr_vector (vector_encoded_msg__s) << ">" << endl;
        }



        // ============ string msg ===============================
        cout << endl << "\tTest#ms2 : Encoding and Decoding string-message using Binary Huffman Tree" << endl;

        string_source_msg__s = "Hi, people! This is string message from Binary Huffman Tree";

        cout << "Source Message  : " << string_source_msg__s << endl;

        if (the_tree.encodeMsg (string_source_msg__s, string_encoded_msg_s))
        {
                cout << "Encoded Message : " << string_encoded_msg_s << endl;
        }
        else
        {
                cout << "Cannot encode Message <" << string_source_msg__s << ">" << endl;
        }

        if (the_tree.decodeMsg (string_encoded_msg_s, string_decoded_msg__s))
        {
                cout << "Decoded Message : " << string_decoded_msg__s << endl;
        }
        else
        {
                cout << "Cannot decode encoded Message <" << string_encoded_msg_s << ">" << endl;
        }

}


// #######################################################
// ################ END OF FILE ##########################
// #######################################################

